package jpb.hotspot;

import jpb.InvalidJvmArgException;
import jpb.JvmArg;
import jpb.MemArg;
import jpb.MemUnit;

import java.util.HashMap;
import java.util.Map;

/**
 * Utility for handling {@link jpb.MemArg}s for Hotspot JVM.
 *
 * @author Dariusz Kordonski
 */
public final class MemArgUtil {

    private static final String MEM_ARG_FORMAT = "%d%s";

    private MemArgUtil() {
        throw new AssertionError("Don't instantiate me");
    }

    private static final Map<MemUnit,String> MEM_UNIT_MAPPING = buildMemArgMappings();
    private static final String MEM_UNIT_NOT_SUPPORTED = "notSupported";


    private static Map<MemUnit,String> buildMemArgMappings() {
        Map<MemUnit,String> memUnitMappings = new HashMap<MemUnit, String>();
        memUnitMappings.put(MemUnit.BITS, MEM_UNIT_NOT_SUPPORTED);
        memUnitMappings.put(MemUnit.BYTES, "");
        memUnitMappings.put(MemUnit.KILOBYTES, "k");
        memUnitMappings.put(MemUnit.MEGABYTES, "m");
        memUnitMappings.put(MemUnit.GIGABYTES, MEM_UNIT_NOT_SUPPORTED);
        memUnitMappings.put(MemUnit.TERABYTES, MEM_UNIT_NOT_SUPPORTED);
        return memUnitMappings;
    }


    public static String formatMemArg(MemArg arg) {
        return String.format(MEM_ARG_FORMAT, arg.quantity(), resolveUnit(arg));
    }

    static String resolveUnit(MemArg arg) {
        return resolveMemUnit(arg.unit());
    }

    static String resolveMemUnit(MemUnit unit) {
        String resolved = MEM_UNIT_MAPPING.get(unit);
        if (notSupported(resolved)) {
            throw new IllegalArgumentException("MemUnit [" + unit + "] not supported by Hotspot");
        }
        return resolved;
    }

    public static String validateMemUnit(MemUnit unit, JvmArg<?> arg) {
        String resolved = MEM_UNIT_MAPPING.get(unit);
        if (notSupported(resolved)) {
            throw new InvalidJvmArgException(arg, unit, "MemUnit <" + unit + "> not supported by Hotspot");
        }
        return resolved;
    }

    private static boolean notSupported(String resolved) {
        return MEM_UNIT_NOT_SUPPORTED.equals(resolved);
    }

}
